package ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl.factory;

import java.util.ArrayList;
import java.util.List;

import ar.com.fiuba.ElectronicCircuitAnalyst.application.api.dto.ComponentDto;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Component;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.ComponentFactory;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Lead;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.LogicalFunctionFactory;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.api.Output;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.common.Specification;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.exceptions.InvalidCircuitElementException;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl.ComponentImpl;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl.LeadImpl;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.impl.OutputImpl;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.specs.InputLeadCanConnectSpecification;
import ar.com.fiuba.ElectronicCircuitAnalyst.domain.specs.OutputLeadCanConnectSpecification;

public class ComponentFactoryImpl implements ComponentFactory {

	private Specification<Component> specification;

	private LogicalFunctionFactory logicalFunctionFactory;

	public ComponentFactoryImpl(Specification<Component> specification, LogicalFunctionFactory logicalFunctionFactory) {
		this.specification = specification;
		this.logicalFunctionFactory = logicalFunctionFactory;
	}

	public Component makeComponent(ComponentDto data) throws InvalidCircuitElementException {
		String name = data.getName();
		String type = data.getType();
		List<Lead> inputLeads = new ArrayList<Lead>();
		List<Output> outputs = new ArrayList<Output>();

		for (int i = 0; i < data.getInputsCounts(); i++) {
			inputLeads.add(new LeadImpl(new InputLeadCanConnectSpecification()));
		}

		for (String function : data.getFunctions()) {
			outputs.add(new OutputImpl(new LeadImpl(new OutputLeadCanConnectSpecification()), logicalFunctionFactory
					.makeLogicalFunction(function)));
		}

		return new ComponentImpl(name, type, inputLeads, outputs, specification);
	}

}
